#include "VtkExamples.h"
#include <vtkSmoothPolyDataFilter.h>
#include "matrix.h"
#include "QDebug"
#include "vtkImageData.h"
#include "vtkImageActor.h"
#include <QList>

void VtkExamples::stripMorph(vtkRenderer *render, int r, int c, int dimCell, double **morph)
{	
	c = 819;
	r = 382;
	dimCell = 10;
	//QUOTA RANDOM
	double **matrixM;
	int  rows=r, cols=c;
	matrixM = new double*[rows];
	for(int i=0;i<rows;i++)	
		matrixM[i] = new double[cols];
	matrixM = readMatrix(matrixM,r,c,"./prova.stt");
	


	// First we'll create some points.
	vtkPoints *points = vtkPoints::New();
	int numPoints = 0;
	for (int i = 0; i < r-1; ++i)
	{
		for (int j = 0; j < c; ++j)
		{
			points->InsertPoint(numPoints++, i*dimCell, j*dimCell, matrixM[i][j]);
		
				points->InsertPoint(numPoints++, i*dimCell+dimCell, j*dimCell, matrixM[i+1][j]);
		}
	}
	vtkCellArray *strips = vtkCellArray::New();
	int tempIndex = 0;
	for (int i = 0; i < r-1; ++i)
	{
		//numero di punti in una riga per formare i triangoli 
		strips->InsertNextCell(c*2);
		for (int j = 0; j < c*2; ++j)
		{
			strips->InsertCellPoint(tempIndex++);
		}
	}
	
	//strips->InsertCellPoint(10);
	vtkPolyData *profile = vtkPolyData::New();
	profile->SetPoints(points);
	profile->SetStrips(strips);
	
	
	vtkPolyDataMapper *map = vtkPolyDataMapper::New();
	
	map->SetInput(profile);
	//map->SetInputConnection(smooth->GetOutputPort());
	vtkActor *strip = vtkActor::New();
	strip->SetMapper(map);
	
	strip->GetProperty()->SetColor(0.3800, 0.7000, 0.1600);
	
	render->AddActor(strip);

	
	copyMatrix(morph,matrixM,0,r,0,c);

	 
}

void VtkExamples::stripFrana(double ** morph, vtkRenderer *render, int r, int c, int dimCell)
{	
	c = 819;
	r = 382;
	
	/*c = 15;
	r = 7;*/
	
	dimCell = 10;
	//QUOTA RANDOM
	double **matrixM;
	
	matrixM = new double*[r];
	for(int i=0;i<r;i++)	
		matrixM[i] = new double[c];
	matrixM = readMatrix(matrixM,r,c,"./colata.stt");
	//CREO L'area da disegnare
	
	
	for (int i = 0; i < r; ++i)
	{
		for (int j = 0; j < c; ++j)
		{
			
			if(matrixM[i][j] != 0.00 && matrixM[i][j] != -1.00){
				VtkExamples::fillNeigh(matrixM,r,c,i,j);
			}
		}
	}

	//QString buffer;
	//for (int i = 0; i < r; ++i)
	//{
	//	for (int j = 0; j < c; ++j)
	//	{

	//		buffer.append(QString::number(matrixM[i][j]));
	//		buffer.append(" ");
	//	}
	//	qDebug() << buffer;
	//	buffer.clear();
	//}



	// First we'll create some points.
	
	vtkPoints *points = vtkPoints::New();
	
	
	QList<int> idList;
	
	vtkCellArray *strips = vtkCellArray::New();
	
	int idPoints = 0;
	for (int i = 0; i < r-1; ++i)
	{
		for (int j = 0; j < c; ++j)
		{
			
			if((matrixM[i][j]==0 || matrixM[i+1][j]==0 || j==c-1) && idList.size()!=0){
				//
				//qDebug() << "SIZE" << idList.size();
				//qDebug() << "RIGA :D" << i;
				strips->InsertNextCell(idList.size());
				int id;
				/*qDebug() << "PUNTI STRIP:";*/

				foreach(id,idList){
					strips->InsertCellPoint(id);
					double* toPrint = new double[3];
					points->GetPoint(id, toPrint);
					/*qDebug() << toPrint[0] << toPrint[1] << toPrint[2]; */ 
				}
				idList.clear();

				/*qDebug() << "FINE";*/
				
				
			}else if(matrixM[i][j]!=0 && matrixM[i+1][j]!=0){
				idList.append(idPoints);
				points->InsertPoint(idPoints++, i*dimCell, j*dimCell, matrixM[i][j]!=-1?matrixM[i][j]+morph[i][j]:0+morph[i][j]-1);
				idList.append(idPoints);
				points->InsertPoint(idPoints++, i*dimCell+dimCell, j*dimCell, matrixM[i+1][j]!=-1?matrixM[i+1][j]+morph[i+1][j]:0+morph[i+1][j]-1);
				
			}
		}
	}
	//int tempIndex = 0;
	//for (int i = 0; i < r-1; ++i)
	//{
	//	//numero di punti in una riga per formare i triangoli 
	//	strips->InsertNextCell(c*2);
	//	for (int j = 0; j < c*2; ++j)
	//	{
	//		strips->InsertCellPoint(tempIndex++);
	//	}
	//}
	vtkPolyData *profile = vtkPolyData::New();
	profile->SetPoints(points);
	profile->SetStrips(strips);
	
	
	
	vtkPolyDataNormals *normal = vtkPolyDataNormals::New();
	normal->SetInput(profile);
	normal->FlipNormalsOn();
	//vtkSmoothPolyDataFilter *smooth = vtkSmoothPolyDataFilter::New();
	//smooth->SetInputConnection(normal->GetOutputPort());
	//smooth->SetNumberOfIterations(20);
	//smooth->SetRelaxationFactor(0.10);
	//
	
	
	vtkPolyDataMapper *map = vtkPolyDataMapper::New();
	//map->SetInput(profile);
	map->SetInputConnection(normal->GetOutputPort());
	vtkLookupTable* lut = vtkLookupTable::New();

	lut->SetTableRange(0.5,11);
	lut->Build();
	lut->SetTableValue(0,1,1,1);
	map->SetLookupTable(lut);
	vtkActor *strip = vtkActor::New();
	strip->SetMapper(map);
	
	
	render->AddActor(strip);

	for (int i = 0; i < r; ++i)
	{
		delete matrixM[i];

	}
	delete matrixM;

	 
}



void VtkExamples::prepareMatrix(double **matrix, int r, int c)
{
	
}

bool VtkExamples::checkNeigh(double **matrix, int r, int c, int i, int j)
{

	for(int x = -1; x <=1 ; x++)
		for(int y = -1; y <= 1; y++)
			if(0 <= i+x && i+x < r && 0 <= j+y && j+y < c)
				if(matrix[i+x][j+y] != 0.0)
					return true;

	return false;
}

void VtkExamples::fillNeigh(double **matrix, int r, int c, int i, int j)
{
	for(int x = -1; x <=1 ; x++)
		for(int y = -1; y <= 1; y++)
			if(0 <= i+x && i+x < r && 0 <= j+y && j+y < c)
				if(matrix[i+x][j+y] == 0.0)
					matrix[i+x][j+y] = -1;
}




void VtkExamples::addText(const char* textString, int x, int y, vtkRenderer *render)
{
	// Create a TextActor
	vtkTextActor* text = vtkTextActor::New();
	text->SetInput(textString);
	vtkTextProperty* tprop = text->GetTextProperty();
	tprop->SetFontFamilyToArial ();
	tprop->BoldOn();
	tprop->ShadowOn();
	tprop->SetLineSpacing(1.0);
	tprop->SetFontSize(50);
	tprop->SetColor(0.0,0.0,1.0);
	tprop->SetOpacity(2.0);
	tprop->SetShadowOffset(2,2);
	text->SetDisplayPosition( x, y );
	render->AddActor2D(text);
}
